#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h> 
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <sys/resource.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stddef.h>
#include <signal.h>
#include "drv_timer.h"
/*
struct SStimer 
{
	int 			type[ MAXIMUM_TIMER ];	
    	drv_timerCallbackTimer 	callback_list[ MAXIMUM_TIMER ];
   	timer_t 		timers_list[ MAXIMUM_TIMER ];
}Stimer;



static void drv_timerHandler(int sig, siginfo_t *si, void *uc)
{
	int i= 0;
	for( i = 0; i < MAXIMUM_TIMER ; i++ )
	{
		if ( si->si_value.sival_ptr == &Stimer.timers_list[ i ] )
		{	
			if(Stimer.callback_list[ i ] != NULL)
			{
				Stimer.callback_list[ i ]();
				if(Stimer.type[ i ] == ONE_SHOT_TIMER )
				{	
					drv_timerStop( i );
				}
			}	
			i = MAXIMUM_TIMER;
		}
	}
}

void drv_timerInit( void )
{
	struct sigaction        sa;
	int i= 0;
	for( i = 0; i < MAXIMUM_TIMER ; i++ )
	{
		Stimer.type[ i ] = ONE_SHOT_TIMER;
		Stimer.callback_list[ i ] = NULL;
		Stimer.timers_list[ i ] = NULL;
	}

	sa.sa_flags = SA_SIGINFO;
	sa.sa_sigaction = drv_timerHandler;
	sigemptyset(&sa.sa_mask);
	if (sigaction(SIGRTMIN, &sa, NULL) == -1)
	{
		printf("Failed to setup signal handling for .\n" );
	}
}

void drv_timerAdd( int timerID, int interval_ns, drv_timerCallbackTimer callback, int type)
{
    	struct sigevent         te;
	struct itimerspec       its;

	Stimer.callback_list[ timerID ] = callback;
	Stimer.type[ timerID ] = type;
	te.sigev_notify = SIGEV_SIGNAL;
	te.sigev_signo = SIGRTMIN;
	te.sigev_value.sival_ptr = &Stimer.timers_list[ timerID ];
	timer_create(CLOCK_REALTIME, &te, &Stimer.timers_list[ timerID ]);
	its.it_interval.tv_sec = 0;
	its.it_interval.tv_nsec = interval_ns * 1000;
	its.it_value.tv_sec = 0;
	its.it_value.tv_nsec = interval_ns * 1000;
	timer_settime(Stimer.timers_list[ timerID ], 0, &its, NULL);
}

void drv_timerStop( int timerID )
{
	timer_delete(Stimer.timers_list[ timerID ]);
	Stimer.type[ timerID ] = ONE_SHOT_TIMER;
	Stimer.callback_list[ timerID ] = NULL;
	Stimer.timers_list[ timerID ] = NULL;
}*/

double drv_timerGetTime( void )
{

#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
	{
		struct timespec ts;
#if defined(CLOCK_MONOTONIC_PRECISE)
		/* BSD. --------------------------------------------- */
		const clockid_t id = CLOCK_MONOTONIC_PRECISE;
#elif defined(CLOCK_MONOTONIC_RAW)
		/* Linux. ------------------------------------------- */
		const clockid_t id = CLOCK_MONOTONIC_RAW;
#elif defined(CLOCK_HIGHRES)
		/* Solaris. ----------------------------------------- */
		const clockid_t id = CLOCK_HIGHRES;
#elif defined(CLOCK_MONOTONIC)
		/* AIX, BSD, Linux, POSIX, Solaris. ----------------- */
		const clockid_t id = CLOCK_MONOTONIC;
#elif defined(CLOCK_REALTIME)
		/* AIX, BSD, HP-UX, Linux, POSIX. ------------------- */
		const clockid_t id = CLOCK_REALTIME;
#else
		const clockid_t id = (clockid_t)-1;	/* Unknown. */
#endif /* CLOCK_* */
		if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 )
			return (double)ts.tv_sec * 1000000000.0 +
				(double)ts.tv_nsec ;
		/* Fall thru. */
	}
#endif /* _POSIX_TIMERS */

	return (double) 0;
}







